/**
 * Copyright (C), 2001-2031, www.bosssof.com.cn
 * FileName: AppLogImpl.java
 * Author: abel.zhan
 * Date: 2024-05-28 14:25
 * Description:
 * 用于时间AppLog注解
 * History:
 * Date          Author   Version  Desc
 * 2024-01-01    bosssoft  1.0.0   initialize this file
 */
package com.bosssoft.common.annotation;

import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.stereotype.Component;

import java.util.Arrays;

/**
 * @className: AppLogImpl
 * @description: 实现以下功能：
 * 该文件提供了一个用于记录使用 @AppLog 注解标记的方法执行情况的切面。
 * 它拦截方法调用并记录方法执行的详细信息，如方法名、参数和执行时间。
 * @author: chen
 * @date: 2024-05-28 14:25
 * @since 1.0
 **/
@Slf4j
@Aspect
@Component
public class AppLogImpl {

    /**
     * 用于定义使用 @AppLog 注解标记的方法的切入点。
     */
    @Pointcut("@annotation(com.bosssoft.common.annotation.AppLog)")
    public void appLog() {
    }

    /**
     * 在方法调用之前和之后记录方法执行的详细信息的通知。
     *
     * @param joinPoint ProceedingJoinPoint 对象，用于访问方法详细信息并继续执行方法。
     * @return 方法执行的结果。
     * @throws Throwable 如果方法执行期间发生错误。
     */
    @Around("appLog()")
    public Object appLog(ProceedingJoinPoint joinPoint) throws Throwable {
        Long startTime = System.currentTimeMillis();

        log.info("开始执行方法 {}", joinPoint.getSignature().getName());
        Object[] params=joinPoint.getArgs();

        Arrays.stream(params).forEach(param->log.info("参数 {}",param));

        Object result = joinPoint.proceed();

        log.info("消耗时间 {}", System.currentTimeMillis() - startTime);

        return result;
    }
}
